package threadcoreknowledge.threadobjectclasscommonmethods;

/**
 * 展示wait和notify的基本方法
 * 1. 研究代碼執行順序
 * 2. 证明wait释放锁
 */
public class Wait {

    public static Object object = new Object();

    // 线程1进入wait状态，被线程2的notify唤醒
    static class Thread1 extends Thread {
        @Override
        public void run() {
            synchronized (object) {
                System.out.println("线程" + Thread.currentThread().getName() + "开始执行了");
                try {

                    //   wait释放锁  程序等待,待其他线程释放锁以后 会继续向下执行
                    object.wait();
                } catch (InterruptedException e) {

                    //在执行等待期间, 如果遇到中断了, 就会抛出 InterruptedException
                    e.printStackTrace();
                }
                System.out.println("线程" + Thread.currentThread().getName() + "获取到了锁");
            }
        }
    }

    // 唤醒线程1的wait
    static class Thread2 extends Thread {
        @Override
        public void run() {
            synchronized (object) {
                /**
                 * 在notify()方法后，当前线程不会马上释放该对象锁，要等到执行notify()方法的线程将程序执行完，
                 * 也就是退出同步代码块之后才会释放对象锁
                 */
                System.out.println("线程" + Thread.currentThread().getName() + "开始调用notify()");
                object.notify();
                System.out.println("线程" + Thread.currentThread().getName() +"notify执行完了....");
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread1 thread1 = new Thread1();
        Thread2 thread2 = new Thread2();
        thread1.start();
        Thread.sleep(200);
        thread2.start();

    }
}
